﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication5
{
	class Program
	{
		

		static List<text_Text> allTexts;
		private static long currentBookTreeId = 0;

		private static long BookTreeId
		{
			get
			{
				bool notfound = true;
				while (notfound)
				{
					currentBookTreeId++;
					if (allTexts.All(x => x.TextId != currentBookTreeId))
						notfound = false;
				}

				return currentBookTreeId;
			}
		}

		private static void Main(string[] args)
		{
			List<text_Book> allBooks;
			List<text_Chapter> allChapters;

			using (SmarlyEntities en = new SmarlyEntities())
			{
				allBooks = en.text_Book.ToList();
				allChapters = en.text_Chapter.ToList();
				allTexts = en.text_Text.ToList();

			}

			foreach (var book in allBooks)
			{
				#region toc

				List<text_Chapter> chapters = allChapters.Where(x => x.BookId == book.BookId).ToList();

				text_Chapter root = chapters.Single(x => x.ParentChapterId == null);
				ToTree(root, chapters);
				book.Chapter = root;

				#endregion

				#region text

				FillText(root, allTexts);

				#endregion

			}

			Console.WriteLine("total lines:" + allTexts.Count);


			using (SqlConnection connection = new SqlConnection("Data Source=.;Initial Catalog=smarly_to_azure;Integrated Security=true;MultipleActiveResultSets=True;Connect Timeout=0;"))
			{
				connection.Open();
				using (DbCommand command = new SqlCommand()
																			{
																				CommandType = CommandType.StoredProcedure,
																				Connection = connection,
																				CommandTimeout = 0,
																				CommandText = "[dbo].[Text_BookTree_Add]",
																			})
				{
					command.Parameters.Add(new SqlParameter("@addParentTreeId", SqlDbType.Int));
					command.Parameters.Add(new SqlParameter("@bookId", SqlDbType.UniqueIdentifier));
					command.Parameters.Add(new SqlParameter("@isHead", SqlDbType.Bit));
					command.Parameters.Add(new SqlParameter("@hashTag", SqlDbType.NVarChar));
					command.Parameters.Add(new SqlParameter("@published", SqlDbType.Bit));
					command.Parameters.Add(new SqlParameter("@text", SqlDbType.NVarChar));
					command.Parameters.Add(new SqlParameter("@currentId", SqlDbType.Int));
					foreach (var book in allBooks)
					{
						Console.WriteLine("Book:" + book.CoverUrl);

						Insert(command, book.Chapter);
					}
				}
			}
		}

		private static void ToTree(text_Chapter root, List<text_Chapter> chapters)
		{
			root.Children = chapters.Where(x => x.ParentChapterId == root.ChapterId).OrderBy(x => x.Order).ToList();
			if (root.Children != null)
				foreach (var child in root.Children)
				{
					child.Parent = root;
					ToTree(child, chapters);
				}
		}

		private static void FillText(text_Chapter root, List<text_Text> texts)
		{
			root.Texts = texts.Where(x => x.ChapterId == root.ChapterId).OrderBy(x => x.Order).ToList();

			if (root.Children != null)
				foreach (var child in root.Children)
				{
					FillText(child, texts);
				}
		}

		private static void Insert(DbCommand command, text_Chapter root)
		{
			long bookTreeId = BookTreeId;
			if (root.Parent != null)
			{
				command.Parameters["@addParentTreeId"].Value = root.Parent.BookTreeId;
			}
			else
			{
				command.Parameters["@addParentTreeId"].Value = null;
			}

			command.Parameters["@bookId"].Value = root.BookId;
			command.Parameters["@isHead"].Value = true;
			command.Parameters["@hashTag"].Value = root.HashTag;
			command.Parameters["@published"].Value = root.IsPublished;
			command.Parameters["@text"].Value = root.Title;
			command.Parameters["@currentId"].Value = bookTreeId;


			root.BookTreeId = bookTreeId;

			command.ExecuteNonQuery();

			long parentId = root.BookTreeId;

			if (root.Texts != null)
				foreach (var txt in root.Texts)
				{
					bool isHead = txt.Tag == "h2";
					if (isHead)
						parentId = root.BookTreeId;

					command.Parameters["@addParentTreeId"].Value = parentId;
					command.Parameters["@isHead"].Value = isHead;
					command.Parameters["@bookId"].Value = root.BookId;
					command.Parameters["@hashTag"].Value = null;
					command.Parameters["@published"].Value = root.IsPublished;
					command.Parameters["@currentId"].Value = txt.TextId;
					command.Parameters["@text"].Value = isHead ? txt.Value : string.Format("<{0} id=\"text-{1}\">{2}</{0}>", txt.Tag, txt.TextId, txt.Value);

					command.ExecuteNonQuery();

					if (isHead)
						parentId = txt.TextId;
				}

			if (root.Children != null)
				foreach (var child in root.Children)
				{
					Insert(command, child);
				}
		}
	}
}

namespace ConsoleApplication5
{
	public partial class text_Chapter
	{
		public List<text_Chapter> Children { get; set; }
		public List<text_Text> Texts { get; set; }
		public text_Chapter Parent { get; set; }

		public long BookTreeId { get; set; }
	}

	public partial class text_Book
	{
		public text_Chapter Chapter { get; set; }
	}

}
